package evolution.cli;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import evolution.Directory;
import evolution.Resource;
import evolution.ResourceException;
import evolution.ResourceVisitor;


public class FileSystemDirectory implements Directory
{
	private final File dir;
	private Directory parent;

	public FileSystemDirectory(File dir)
	{
		this.dir = dir;
	}

	public void addMember(Resource resource) throws ResourceException
	{
		resource.setParent(this);
		if (resource instanceof evolution.File)
		{
			File file = new File(dir, ((evolution.File) resource).getName());
			if (resource instanceof TransientFile)
			{
				FileSystemFile tres = new FileSystemFile(file);
				tres.setParent(this);
				((evolution.cli.TransientFile) resource).etherealize(tres);
			}
		}
		else if (resource instanceof Directory)
		{
			if (resource instanceof TransientDirectory)
			{
				TransientDirectory tdir = (TransientDirectory) resource;
				File newDirFile = new File(dir, tdir.getName());
				FileSystemDirectory tres = new FileSystemDirectory(newDirFile);
				tres.setParent(this);
				tdir.etherealize(tres);
			}
		}
	}

	public Resource getMember(String name)
	{
		File result = new File(dir, name);
		if (result.exists())
		{
			if (result.isFile())
			{
				Resource res = new FileSystemFile(result);
				res.setParent(this);
				return res;
			}
			else if (result.isDirectory())
			{
				FileSystemDirectory res = new FileSystemDirectory(result);
				res.setParent(this);
				return res;
			}
		}
		return null;
	}

	public String getName()
	{
		return dir.getName();
	}

	public void deleteMember(String name)
	{
		File file = new File(dir, name);
		if (file.exists())
		{
			deleteFile(file);
		}
	}

	private static void deleteFile(File file)
	{
		if (file.isDirectory())
		{
			for (File child : file.listFiles())
			{
				deleteFile(child);
			}
		}
		file.delete();
	}

	@Override
	public String toString()
	{
		return dir.toString();
	}

	public Iterator<Resource> iterator()
	{
		List<Resource> results = new ArrayList<Resource>();
		for (File file : dir.listFiles())
		{
			if (file.isDirectory())
			{
				FileSystemDirectory fsd = new FileSystemDirectory(file);
				fsd.setParent(this);
				results.add(fsd);
			}
			else
			{
				FileSystemFile fsf = new FileSystemFile(file);
				fsf.setParent(this);
				results.add(fsf);
			}
		}
		return results.iterator();
	}

	public void setParent(Directory parent)
	{
		this.parent = parent;
	}

	public void mkdir()
	{
		dir.mkdir();
	}

	public String getPath()
	{
		if (parent != null)
		{
			String parentPath = parent.getPath();
			if (parentPath.equals("/"))
			{
				return "/" + getName();
			}
			else
			{
				return parentPath + "/" + getName();
			}
		}
		else
		{
			return getName();
		}
	}

	public long getLastModifiedTime()
	{
		return dir.lastModified();
	}

	public void accept(ResourceVisitor visitor)
	{
		throw new UnsupportedOperationException("TODO");
	}

}
